﻿package gas.extractors.linux;

import java.io.*;
import java.util.*;
import java.lang.*;
import java.text.*;


/**
 * Clase creada para almacenar toda la información del usuario que se necesitará
 */
class Usuario {
	String id = "";
	String user_code = "";
	String full_name = "";
	String comments = "";
	String accountStatus = "";
	String passwordExpired = "0";
	String accountExpires = "0";
	String hostAudit = "";

	public Usuario(String hostAudit) {
		this.hostAudit = hostAudit;
	}

	public String getId() {
		return this.id;
	}

	public void setId(String aux) {
		this.id = aux;
	}

	public void setUserCode(String aux) {
		this.user_code = aux;
	}

	public void setFullName(String aux) {
		this.full_name = aux;
	}

	public void setComments(String aux) {
		this.comments = aux;
	}

	public void setAccountStatus(String aux) {
		this.accountStatus = aux;
	}

	public void setPasswordExpired(String aux) {
		this.passwordExpired = aux;
	}

	public void setAccountExpires(String aux) {
		this.accountExpires = aux;
	}

	public String toString() {
		String salida = new String();

		salida = "\t<GAS_USERS>\n";
		salida += "\t\t<ID>" + id + "</ID>\n";
		salida += "\t\t<USER_CODE>" + user_code + "</USER_CODE>\n";
		salida += "\t\t<FULL_NAME>" + full_name + "</FULL_NAME>\n";
		salida += "\t\t<COMMENTS>" + comments + "</COMMENTS>\n";
		salida += "\t\t<ACCOUNT_STATUS>" + accountStatus
				+ "</ACCOUNT_STATUS>\n";
		salida += "\t\t<PASSWORD_EXPIRED>" + passwordExpired
				+ "</PASSWORD_EXPIRED>\n";
		salida += "\t\t<ACCOUNT_EXPIRES>" + accountExpires
				+ "</ACCOUNT_EXPIRES>\n";
		salida += "\t\t<HOST_AUDIT>" + hostAudit + "</HOST_AUDIT>\n";
		salida += "\t</GAS_USERS>";

		return salida;
	}
}

/**
 * CLASE EXTRACTOR EN SÍ
 * 
 * @author root
 * 
 */
public class Extractor {

	// Número de hostAudit que se establecera la primera vez que se conecte con
	// el servicio web
	private static int hostAudit = -1;
	// Variable utilizada para llevar cuenta del número de logs incluidos
	private static int indLogs;

	/**
	 * Funcion que obtiene los usuarios y grupos del sistema a auditar
	 * 
	 * @return
	 */
	public static String obtenerUsersGroups() {
		String salida = new String();
		String salida2 = new String();
		// Tabla de usuarios
		Hashtable table = new Hashtable();

		// Extracción de los usuarios
		Runtime r = Runtime.getRuntime();
		Process p = null;

		try {
			p = r.exec("cat /etc/passwd");
			p.waitFor();
			// Se obtiene el stream de salida del programa
			InputStream is = p.getInputStream();

			/*
			 * Se prepara un bufferedReader para poder leer la salida más
			 * comodamente.
			 */
			BufferedReader br = new BufferedReader(new InputStreamReader(is));

			// Se lee la primera linea
			String aux = br.readLine();
			int i = -1;
			while (aux != null) {
				StringTokenizer st = new StringTokenizer(aux, ":");
				String name = st.nextToken();
				String passwd = st.nextToken();
				String status = "";
				if (passwd.intern().equals("*")) {
					status = "Disabled: True; Lockout: False; Status: NOT OK";
				} else if (passwd.intern().equals("!!")) {
					status = "Disabled: False; Lockout: True; Status: NOT OK";
				} else {
					status = "Disabled: False; Lockout: False; Status: OK";
				}

				// Creo una instancia grupo
				Usuario user = new Usuario(Integer.toString(hostAudit));
				user.setId(Integer.toString(i));
				user.setUserCode(name);
				user.setAccountStatus(status);
				table.put(name, user);
				i--;
				aux = br.readLine();
			}
		} catch (Exception e) {
		}

		try {
			p = r.exec("cat /etc/shadow");
			p.waitFor();
			// Se obtiene el stream de salida del programa
			InputStream is = p.getInputStream();

			/*
			 * Se prepara un bufferedReader para poder leer la salida más
			 * comodamente.
			 */
			BufferedReader br = new BufferedReader(new InputStreamReader(is));

			// Se lee la primera linea
			String aux = br.readLine();
			while (aux != null) {
				StringTokenizer st = new StringTokenizer(aux, ":");
				String name = st.nextToken();
				String passwd = st.nextToken();
				Usuario user = null;
				if (table.get(name) != null)
					user = (Usuario) table.get(name);
				if (passwd.intern().equals("*")) {
					String changed = st.nextToken();
					String minlife = st.nextToken();
					String maxlife = st.nextToken();

					if (!(minlife.intern().equals("") || (minlife.intern()
							.equals("0") && maxlife.intern().equals("99999")))) {
						int resta = Integer.parseInt(maxlife)
								- Integer.parseInt(changed);
						user.setPasswordExpired(Integer.toString(resta));
					}
					st.nextToken();
					if (st.hasMoreTokens()) {
						String expired = st.nextToken();
						if (!(expired.intern().equals("") || expired.intern()
								.equals("0"))) {
							user.setPasswordExpired("1");
						}
					}
				}
				// if (user != null)
				// salida += user.toString();
				aux = br.readLine();
			}
		} catch (Exception e) {
		}

		Enumeration enum1 = table.elements();

		while (enum1.hasMoreElements()) {
			Usuario user = (Usuario) enum1.nextElement();
			salida += user.toString();
		}

		// Extracción de los grupos

		try {
			p = r.exec("cat /etc/group");
			p.waitFor();
			// Se obtiene el stream de salida del programa
			InputStream is = p.getInputStream();

			/*
			 * Se prepara un bufferedReader para poder leer la salida más
			 * comodamente.
			 */
			BufferedReader br = new BufferedReader(new InputStreamReader(is));

			// Se lee la primera linea
			String aux = br.readLine();
			int i = -1;
			int i2 = -1;
			while (aux != null) {
				StringTokenizer st = new StringTokenizer(aux, ":");
				String name = st.nextToken();
				salida += "\t<GAS_GROUPS>\n";
				salida += "\t\t<ID>" + i + "</ID>\n";
				salida += "\t\t<GROUP_NAME>" + name + "</GROUP_NAME>\n";
				salida += "\t\t<GROUP_TYPE>True</GROUP_TYPE>\n";
				salida += "\t\t<HOST_AUDIT>" + hostAudit + "</HOST_AUDIT>\n";
				salida += "\t</GAS_GROUPS>\n";

				st.nextToken();
				st.nextToken();
				String usuarios = aux.substring(aux.lastIndexOf(":") + 1, aux
						.length());
				if (!(usuarios.intern().equals(""))) {
					StringTokenizer usu = new StringTokenizer(usuarios, ",");
					Usuario user = null;
					while (usu.hasMoreTokens()) {
						String usuAux = usu.nextToken();
						if (table.get(usuAux) != null) {
							user = (Usuario) table.get(usuAux);
							salida2 += "\t<GAS_USER_GROUPS>\n";
							salida2 += "\t\t<ID>" + i2 + "</ID>\n";
							salida2 += "\t\t<GAS_USER>" + user.getId()
									+ "</GAS_USER>\n";
							salida2 += "\t\t<GAS_GROUP>" + i + "</GAS_GROUP>\n";

							salida2 += "\t</GAS_USER_GROUPS>\n";
							i2--;
						}
					}
				}

				i--;
				aux = br.readLine();
			}
		} catch (Exception e) {
		}
		salida += salida2;

		return salida;
	}

	/**
	 * Funcion que obtiene los parametros de seguridad del sistema a auditar
	 * 
	 * @return
	 */
	public static String obtenerSecuritySettings() {
		String salida = new String();

		Runtime r = Runtime.getRuntime();
		Process p = null;

		try {
			p = r.exec("cat /etc/login.defs");
			p.waitFor();
			// Se obtiene el stream de salida del programa
			InputStream is = p.getInputStream();

			/*
			 * Se prepara un bufferedReader para poder leer la salida más
			 * comodamente.
			 */
			BufferedReader br = new BufferedReader(new InputStreamReader(is));

			// Se lee la primera linea
			String aux = br.readLine();
			int i = 0;
			while ((aux != null) && (i < 16)) {
				i++;
				aux = br.readLine();
			}
			int i2 = -1;
			while ((aux != null) && (!(aux.intern().equals("")))) {
				StringTokenizer st = new StringTokenizer(aux);
				String setting = st.nextToken();
				String value = st.nextToken();
				salida += "\t<GAS_SECURITY_SETTINGS>\n";
				salida += "\t\t<ID>" + i2 + "</ID>\n";
				salida += "\t\t<NAME>" + setting + "</NAME>\n";
				salida += "\t\t<VALUE>" + value + "</VALUE>\n";
				salida += "\t\t<HOST_AUDIT>" + hostAudit + "</HOST_AUDIT>\n";
				salida += "\t</GAS_SECURITY_SETTINGS>\n";
				i2--;
				aux = br.readLine();
			}
		} catch (Exception e) {
		}
		return salida;
	}

	/**
	 * Función que obtiene los puertos abiertos del sistema a auditar
	 * 
	 * @return
	 */
	public static String obtenerOpenPorts() {
		String salida = "";

		Runtime r = Runtime.getRuntime();
		Process p = null;

		try {
			p = r.exec("nmap localhost");
			p.waitFor();
			// Se obtiene el stream de salida del programa
			InputStream is = p.getInputStream();

			/*
			 * Se prepara un bufferedReader para poder leer la salida más
			 * comodamente.
			 */
			BufferedReader br = new BufferedReader(new InputStreamReader(is));

			// Se lee la primera linea
			String aux = br.readLine();
			int i = 0;
			while ((aux != null) && (i < 5)) {
				i++;
				aux = br.readLine();
			}

			int i2 = -1;
			while ((aux != null) && (!(aux.intern().equals("")))) {
				StringTokenizer st = new StringTokenizer(aux);
				int i1 = 0;
				String numero = null;
				String tipo = null;
				String aplicacion = null;
				while (st.hasMoreTokens()) {
					String auxiliar = st.nextToken();
					if (i1 == 0) {
						numero = auxiliar.substring(0, auxiliar.indexOf("/"));
						tipo = auxiliar.substring(auxiliar.indexOf("/") + 1,
								auxiliar.length());
					} else if (i1 == 2) {
						aplicacion = auxiliar;
					}
					i1++;
				}
				salida += "\t<GAS_OPEN_PORTS>\n";
				salida += "\t\t<ID>" + i2 + "</ID>\n";
				salida += "\t\t<PORT_NUMBER>" + numero + "</PORT_NUMBER>\n";
				salida += "\t\t<PORT_TYPE>" + tipo + "</PORT_TYPE>\n";
				salida += "\t\t<MORE_DETAILS></MORE_DETAILS>\n";
				salida += "\t\t<STATE>LISTEN</STATE>\n";
				salida += "\t\t<SERVICE>" + aplicacion + "</SERVICE>\n";
				salida += "\t\t<HOST_AUDIT>" + hostAudit + "</HOST_AUDIT>\n";
				salida += "\t</GAS_OPEN_PORTS>\n";
				i2--;
				aux = br.readLine();
			}
		} catch (Exception e) {
		}
		return salida;
	}

	/**
	 * FALTA POR HACER
	 * 
	 * @return
	 */
	public static String obtenerNetworkAdapters() {
		String salida = new String();

		Runtime r = Runtime.getRuntime();
		Process p = null;

		try {
			p = r.exec("ifconfig");
			p.waitFor();
			// Se obtiene el stream de salida del programa
			InputStream is = p.getInputStream();

			/*
			 * Se prepara un bufferedReader para poder leer la salida más
			 * comodamente.
			 */
			BufferedReader br = new BufferedReader(new InputStreamReader(is));
			boolean primeravez = true;
			// Se lee la primera linea
			String aux = br.readLine();
			int i = -1;
			while (aux != null) {
				primeravez = true;
				StringTokenizer st = new StringTokenizer(aux);
				String name = st.nextToken().trim();
				String MAC = "";
				if (!(name.intern().equals("lo"))) {
					st.nextToken();
					st.nextToken();
					st.nextToken();
					MAC = st.nextToken().trim();

					while (!(aux.intern().equals(""))) {
						if (primeravez) {
							name = aux.substring(0, aux.indexOf(" ")).trim();

							aux = br.readLine();

							StringTokenizer st1 = new StringTokenizer(aux);
							st1.nextToken();
							String aux2 = st1.nextToken().trim();
							String ip = aux2.substring(aux2.indexOf(":") + 1,
									aux2.length());

							st1.nextToken().trim();

							aux2 = st1.nextToken().trim();
							String mask = aux2.substring(aux2.indexOf(":") + 1,
									aux2.length());

							Runtime r1 = Runtime.getRuntime();
							Process p1 = null;
							String gw = "";
							try {
								p1 = r1.exec("route");
								p1.waitFor();
								// Se obtiene el stream de salida del programa
								InputStream is1 = p1.getInputStream();

								BufferedReader br1 = new BufferedReader(
										new InputStreamReader(is1));

								String aux3 = br1.readLine();
								while (aux3 != null) {
									StringTokenizer st2 = new StringTokenizer(
											aux3);
									if (st2.nextToken().intern().equals(
											"default")) {
										gw = st2.nextToken().trim();
									}
									aux3 = br1.readLine();
								}
							} catch (Exception e) {
							}

							salida += "\t<GAS_NET_ADAPTERS>\n";
							salida += "\t\t<ID>" + i + "</ID>\n";
							salida += "\t\t<ADAPTER_NAME>" + name
									+ "</ADAPTER_NAME>\n";
							salida += "\t\t<IP_ADDRESS>" + ip
									+ "</IP_ADDRESS>\n";
							salida += "\t\t<SUBNET_MASK>" + mask
									+ "</SUBNET_MASK>\n";
							salida += "\t\t<DEFAULT_GW>" + gw
									+ "</DEFAULT_GW>\n";
							salida += "\t\t<MAC_ADDRESS>" + MAC
									+ "</MAC_ADDRESS>\n";
							salida += "\t\t<DHCP_ENABLED>0</DHCP_ENABLED>\n";
							salida += "\t\t<HOST_AUDIT>" + hostAudit
									+ "</HOST_AUDIT>\n";
							salida += "\t</GAS_NET_ADAPTERS>\n";

							i--;
							primeravez = false;
						}
						aux = br.readLine();
					}
				} else {
					salida += "\t<GAS_NET_ADAPTERS>\n";
					salida += "\t\t<ID>-1</ID>\n";
					salida += "\t\t<ADAPTER_NAME>lo</ADAPTER_NAME>\n";
					salida += "\t\t<IP_ADDRESS>127.0.0.1</IP_ADDRESS>\n";
					salida += "\t\t<SUBNET_MASK>255.0.0</SUBNET_MASK>\n";
					salida += "\t\t<DEFAULT_GW></DEFAULT_GW>\n";
					salida += "\t\t<MAC_ADDRESS></MAC_ADDRESS>\n";
					salida += "\t\t<DHCP_ENABLED/>\n";
					salida += "\t\t<HOST_AUDIT>" + hostAudit
							+ "</HOST_AUDIT>\n";
					salida += "\t</GAS_NET_ADAPTERS>\n";
				}
				aux = br.readLine();
			}
		} catch (Exception e) {
		}
		return salida;
	}

	public static String obtenerUpdates() {
		String salida = new String();

		Runtime r = Runtime.getRuntime();
		Process p = null;

		try {
			p = r.exec("uname -orv");
			p.waitFor();
			// Se obtiene el stream de salida del programa
			InputStream is = p.getInputStream();

			/*
			 * Se prepara un bufferedReader para poder leer la salida más
			 * comodamente.
			 */
			BufferedReader br = new BufferedReader(new InputStreamReader(is));

			// Se lee la primera linea
			String aux = br.readLine();

			StringTokenizer st = new StringTokenizer(aux, "#");
			String name = st.nextToken().trim();
			String version = st.nextToken();
			salida += "\t<GAS_SO_UPDATES>\n";
			salida += "\t\t<ID>-1</ID>\n";
			salida += "\t\t<NAME>" + name + "</NAME>\n";
			if (version.length() > 30)
				version = version.substring(0, 30);
			salida += "\t\t<VERSION>" + version + "</VERSION>\n";
			salida += "\t\t<DESCRIPTION/>\n";
			salida += "\t\t<HOST_AUDIT>" + hostAudit + "</HOST_AUDIT>\n";
			salida += "\t</GAS_SO_UPDATES>\n";
		} catch (Exception e) {
		}
		return salida;
	}

	/**
	 * Funcion utilizada por la función obtenerLogs para leer ficheros
	 * /var/log/messages*
	 * 
	 * @param terminacion
	 * @return
	 */
	public static String verFichero(String terminacion) {

		String salida = "";
		try {
			FileInputStream fs = new FileInputStream("/var/log/messages"
					+ terminacion);
			InputStreamReader isr = new InputStreamReader(fs);
			BufferedReader br = new BufferedReader(isr);
			// Se lee la primera linea
			String aux = br.readLine();

			while (aux != null) {

				StringTokenizer st = new StringTokenizer(aux);
				String timeGenerated = st.nextToken();
				timeGenerated += " " + st.nextToken();
				timeGenerated += " " + st.nextToken();
				st.nextToken();
				String source = "";
				while (st.hasMoreTokens()) {
					source += st.nextToken() + " ";
				}

				String salida2 = "";
				salida2 += "\t<GAS_LOGS>\n";
				salida2 += "\t\t<ID>" + indLogs + "</ID>\n";
				
/**				Date dateGenerated;
				
				try
				{
					dateGenerated = Date..parse(timeGenerated);
					salida2 += "\t\t<TIME_GENERATED>" + (dateGenerated.getYear()+1900) + "-" + dateGenerated.getMonth() + dateGenerated.getDay() + "T" + dateGenerated.getHours() + ":" + dateGenerated.getMinutes() + ":" + dateGenerated.getSeconds();
					+ "</TIME_GENERATED>\n";
				}
				catch
				{
				}
*/				
				
				salida2 += "\t\t<SOURCE>" + source.replaceAll("<", "").replace(">", "") + "</SOURCE>\n";
				salida2 += "\t\t<DESCRIPTION>\n\t\t\t\n\t\t</DESCRIPTION>\n";
				salida2 += "\t\t<HOST_AUDIT>" + hostAudit + "</HOST_AUDIT>\n";
				salida2 += "\t</GAS_LOGS>\n";
				salida += salida2;
				indLogs--;
				aux = br.readLine();
			}
		} catch (Exception e) {
		}
		return salida;
	}

	/**
	 * Funcion para obtener los logs del sistema a auditar
	 * 
	 * @return
	 */
	public static String obtenerLogs() {
		String salida = "";

		/* Un fichero de mensajes tiene seguro */
		indLogs = -1;
		salida += verFichero("");
		for (int i = 1; i < 6; i++) {
			salida += verFichero("." + Integer.toString(i));
		}
		return salida;
	}

	/**
	 * Funcion para obtener el hardware del sistema a auditar
	 * 
	 * @return
	 */
	public static String obtenerHardware() {
		String salida = new String();

		Runtime r = Runtime.getRuntime();
		Process p = null;
		int i = -1;
		try {
			p = r.exec("lspci -m");
			p.waitFor();

			InputStream is = p.getInputStream();

			BufferedReader br = new BufferedReader(new InputStreamReader(is));

			String aux = br.readLine();
			while (aux != null) {

				aux = aux.substring(aux.indexOf(" ") + 2, aux.length());

				String typeDevice = aux.substring(0, aux.indexOf("\""));

				aux = aux.substring(aux.indexOf("\"") + 3, aux.length());

				String manufacturer = aux.substring(0, aux.indexOf("\""));

				aux = aux.substring(aux.indexOf("\"") + 3, aux.length());

				String device = aux.substring(0, aux.indexOf("\""));

				aux = aux.substring(aux.indexOf("\"") + 3, aux.length());
				aux = aux.substring(aux.indexOf("\"") + 1, aux.length());

				String softVendor = aux.substring(0, aux.indexOf("\""));

				aux = aux.substring(aux.indexOf("\"") + 3, aux.length());

				String softDev = aux.substring(0, aux.indexOf("\""));

				salida += "\t<GAS_HW_DEVICES>\n";
				salida += "\t\t<ID>" + i + "</ID>\n";
				salida += "\t\t<DEVICE_NAME>" + device + "</DEVICE_NAME>\n";
				salida += "\t\t<DESCRIPTION>\n" + "\t\t\tClass of Device: "
						+ typeDevice + ";\n"
						+ "\t\t\tVendor of Device's Software: " + softVendor
						+ ";\n" + "\t\t\tDevice's Software: " + softDev + ";\n"
						+ "\t\t</DESCRIPTION>\n";
				salida += "\t\t<VERSION/>\n";
				salida += "\t\t<MANUFACTURER>" + manufacturer
						+ "</MANUFACTURER>\n";
				salida += "\t\t<HOST_AUDIT>" + hostAudit + "</HOST_AUDIT>\n";
				salida += "\t</GAS_HW_DEVICES>\n";

				i--;
				aux = br.readLine();
			}
		} catch (Exception e) {
		}

		try {
			p = r.exec("cat /proc/cpuinfo");
			p.waitFor();

			InputStream is = p.getInputStream();

			BufferedReader br = new BufferedReader(new InputStreamReader(is));

			String aux = br.readLine();
			aux = br.readLine();

			String manufacturer = aux.substring(aux.indexOf(":") + 2, aux
					.length());

			String typeDevice = "CPU";

			aux = br.readLine();
			aux = br.readLine();
			aux = br.readLine();

			String device = aux.substring(aux.indexOf(":") + 2, aux.length());

			aux = br.readLine();
			String aux1 = br.readLine();
			String aux2 = br.readLine();

			salida += "\t<GAS_HW_DEVICES>\n";
			salida += "\t\t<ID>" + i + "</ID>\n";
			salida += "\t\t<DEVICE_NAME>" + device + "</DEVICE_NAME>\n";
			salida += "\t\t<DESCRIPTION>\n" + "\t\t\tClass of Device : "
					+ typeDevice + ";\n" + "\t\t\t" + aux1 + ";\n" + "\t\t\t"
					+ aux2 + ";\n" + "\t\t</DESCRIPTION>\n";
			salida += "\t\t<VERSION/>\n";
			salida += "\t\t<MANUFACTURER>" + manufacturer + "</MANUFACTURER>\n";
			salida += "\t\t<HOST_AUDIT>" + hostAudit + "</HOST_AUDIT>\n";
			salida += "\t</GAS_HW_DEVICES>\n";

			i--;
		} catch (Exception e) {
		}

		try {
			p = r.exec("cat /proc/partitions");
			p.waitFor();

			InputStream is = p.getInputStream();

			BufferedReader br = new BufferedReader(new InputStreamReader(is));

			String aux = br.readLine();
			aux = br.readLine();
			aux = br.readLine();

			while (aux != null) {
				String particion = aux.substring(aux.lastIndexOf(" "), aux
						.length());
				try {
					int numero = Integer.parseInt(particion.substring(particion
							.length() - 1, particion.length()));
				} catch (Exception e) {
					StringTokenizer st = new StringTokenizer(aux);
					st.nextToken();
					st.nextToken();
					String numBlocks = st.nextToken();

					salida += "\t<GAS_HW_DEVICES>\n";
					salida += "\t\t<ID>" + i + "</ID>\n";
					salida += "\t\t<DEVICE_NAME>" + particion
							+ "</DEVICE_NAME>\n";
					salida += "\t\t<DESCRIPTION>\n"
							+ "\t\t\tClass of Device : Disk of Memory;\n"
							+ "\t\t\tBlocks of Memory : " + numBlocks + ";\n"
							+ "\t\t</DESCRIPTION>\n";
					salida += "\t\t<VERSION/>\n";
					salida += "\t\t<MANUFACTURER/>\n";
					salida += "\t\t<HOST_AUDIT>" + hostAudit
							+ "</HOST_AUDIT>\n";
					salida += "\t</GAS_HW_DEVICES>\n";

					i--;
				}
				aux = br.readLine();
			}
		} catch (Exception e) {
		}

		return salida;
	}

	/**
	 * Funcion que obtiene el software del sistema a auditar
	 * 
	 * @return
	 */
	public static String obtenerSoftware() {
		String salida = "";
		boolean repetir = false;

		Runtime r = Runtime.getRuntime();
		Process p = null;
		try {
			System.out.println("Before executing rpm -qa");
			p = r.exec("rpm -qa");
			p.waitFor();
			System.out.println("After executing rpm -qa");

			// Se obtiene el stream de salida del programa
			InputStream is = p.getInputStream();

			/*
			 * Se prepara un bufferedReader para poder leer la salida más
			 * comodamente.
			 */
			BufferedReader br = new BufferedReader(new InputStreamReader(is));

			// Se lee la primera linea
			String aux = br.readLine();
			if (!(aux.intern().equals(" "))) {
				int i = -1;
				while (aux != null) {
					String salida2 = "";
					Runtime r1 = Runtime.getRuntime();
					Process p1 = null;
					try {
						System.out.println("Before executing rpm -qa --info");
						p1 = r1.exec("rpm -q --info " + aux);
						p1.waitFor();
						System.out.println("After executing rpm -qa --info");

						// Se obtiene el stream de salida del programa
						InputStream is1 = p1.getInputStream();

						/*
						 * Se prepara un bufferedReader para poder leer la
						 * salida más comodamente.
						 */
						BufferedReader br1 = new BufferedReader(
								new InputStreamReader(is1));

						// Se lee la primera linea
						String aux1 = br1.readLine();

						StringTokenizer st = new StringTokenizer(aux1, ":");
						String auxiliar = st.nextToken();
						auxiliar = st.nextToken().trim();
						String name = auxiliar.substring(0, auxiliar
								.indexOf(" "));

						// Se lee la segunda linea
						aux1 = br1.readLine();

						st = new StringTokenizer(aux1, ":");
						auxiliar = st.nextToken();
						auxiliar = st.nextToken().trim();
						String version = auxiliar.substring(0, auxiliar
								.indexOf(" "));
						String vendor = st.nextToken().trim();

						// Se lee la cuarta linea
						aux1 = br1.readLine();
						aux1 = br1.readLine();

						st = new StringTokenizer(aux1, ":");
						auxiliar = st.nextToken();
						auxiliar = st.nextToken().trim();
						String installDate = auxiliar.substring(0, auxiliar
								.length() - 3);

						aux1 = br1.readLine();

						st = new StringTokenizer(aux1, ":");
						auxiliar = st.nextToken();
						auxiliar = st.nextToken();

						auxiliar = st.nextToken();
						String rpmSource = auxiliar.trim();

						aux1 = br1.readLine();
						aux1 = br1.readLine();
						aux1 = br1.readLine();
						aux1 = br1.readLine();
						st = new StringTokenizer(aux1, ":");
						auxiliar = st.nextToken();
						auxiliar = st.nextToken();
						String summary = auxiliar.trim();

						salida2 += "\t<GAS_SOFTWARE_APPS>\n";
						salida2 += "\t\t<ID>" + i + "</ID>\n";
						salida2 += "\t\t<NAME>" + name + "</NAME>\n";
						salida2 += "\t\t<DESCRIPTION>\n"
								+ "\t\t\tInstallDate: " + installDate + ";\n"
								+ "\t\t\tVendor: " + vendor + ";\n"
								+ "\t\t\tRPMSource: " + rpmSource + ";\n"
								+ "\t\t\tSummary: " + summary + ";\n"
								+ "\t\t</DESCRIPTION>\n";
						salida2 += "\t\t<VERSION>" + version + "</VERSION>\n";
						salida2 += "\t\t<HOST_AUDIT>" + hostAudit
								+ "</HOST_AUDIT>\n";
						salida2 += "\t</GAS_SOFTWARE_APPS>";
						salida += salida2;
					} catch (Exception e) {
					}

					i--;
					aux = br.readLine();
				}
			} else {
				repetir = true;
			}
		} catch (Exception e) {
			System.out.println("Exception while executing rpm -qa");
			repetir = true;
		}

		if (repetir) {
/**			try {
				Runtime r2 = Runtime.getRuntime();
				Process p2 = null;

				System.out.println("Before executing apt-cache pkgnames");
				p2 = r2.exec("apt-cache pkgnames");
				p2.waitFor();
				System.out.println("After executing apt-cache pkgnames");

				// Se obtiene el stream de salida del programa
				InputStream is = p2.getInputStream();

				BufferedReader br = new BufferedReader(
						new InputStreamReader(is));

				// Se lee la primera linea
				String aux = br.readLine().trim();
				int i = -1;
				while (aux != null) {
					String salida2 = "";
					salida2 += "\t<GAS_SOFTWARE_APPS>\n";
					salida2 += "\t\t<ID>" + i + "</ID>\n";
					salida2 += "\t\t<NAME>" + aux + "</NAME>\n";
					salida2 += "\t\t<DESCRIPTION/>\n";
					salida2 += "\t\t<VERSION/>>\n";
					salida2 += "\t\t<HOST_AUDIT>" + hostAudit
							+ "</HOST_AUDIT>\n";
					salida2 += "\t</GAS_SOFTWARE_APPS>";
					salida += salida2;
					i--;
					aux = br.readLine().trim();
				}
			} catch (Exception e) {
				System.out.println("Exception while executing apt-cache pkgnames");
			}
*/
		}
		return salida;
	}

	/*
	 * Funcion que obtiene el software del sistema a auditar @return
	 */
	public static String obtenerProcesos() {
		String salida = "";

		Runtime r = Runtime.getRuntime();
		Process p = null;
		int memoriaBytes = 0;

		// Obtener el número de bytes de memoria
		try {
			p = r.exec("cat /proc/meminfo");
			p.waitFor();

			InputStream is = p.getInputStream();

			BufferedReader br = new BufferedReader(new InputStreamReader(is));

			String aux = br.readLine();

			StringTokenizer st = new StringTokenizer(aux);
			st.nextToken();
			String memoriaKBs = st.nextToken();
			memoriaBytes = Integer.parseInt(memoriaKBs) * 1024;
		} catch (Exception e) {
		}

		int i = -1;
		// Obtener los procesos
		try {
			p = r.exec("ps -aux");
			p.waitFor();

			InputStream is = p.getInputStream();

			BufferedReader br = new BufferedReader(new InputStreamReader(is));

			br.readLine();
			String aux = br.readLine();
			while (aux != null) {
				StringTokenizer st = new StringTokenizer(aux);
				st.nextToken();
				st.nextToken();
				st.nextToken();
				String porcentajeMem = st.nextToken();
				long aBytes = Math.round(Double.parseDouble(porcentajeMem)
						* memoriaBytes);
				st.nextToken();
				st.nextToken();
				st.nextToken();
				st.nextToken();
				st.nextToken();

				String execTime = st.nextToken();
				StringTokenizer staux = new StringTokenizer(execTime.trim(),
						":");
				String horas = staux.nextToken();
				String minutos = staux.nextToken();
				long milisegundos = Math
						.round(((Double.parseDouble(horas) * 3600) + (Double
								.parseDouble(minutos) * 60)) * 1000);

				String process = st.nextToken();

				salida += "\t<GAS_PROCESSES>\n";
				salida += "\t\t<ID>" + i + "</ID>\n";
				salida += "\t\t<NAME>" + process + "</NAME>\n";
				salida += "\t\t<EXEC_TIME>" + milisegundos + "</EXEC_TIME>\n";
				salida += "\t\t<MEMORY_BYTES>" + aBytes + "</MEMORY_BYTES>\n";
				salida += "\t\t<HOST_AUDIT>" + hostAudit + "</HOST_AUDIT>\n";
				salida += "\t</GAS_PROCESSES>\n";
				i--;
				aux = br.readLine();
			}
		} catch (Exception e) {
		}

		return salida;
	}

	/**
	 * Función que devuelve el hostID del sistema que estamos auditando
	 * 
	 * @return
	 */
	public static String obtenerHostID() {
		String salida = new String();

		Runtime r = Runtime.getRuntime();
		Process p = null;

		try {
			p = r.exec("uname -n");
			p.waitFor();
			// Se obtiene el stream de salida del programa
			InputStream is = p.getInputStream();

			/*
			 * Se prepara un bufferedReader para poder leer la salida más
			 * comodamente.
			 */
			BufferedReader br = new BufferedReader(new InputStreamReader(is));

			// Se lee la primera linea
			salida = br.readLine().trim();

		} catch (Exception e) {
		}
		return salida;
	}

	/**
	 * Función que devuelve la fecha actual del momento de la auditoría
	 * 
	 * @return
	 */
	public static String obtenerFecha() {
		String salida = new String();

		Runtime r = Runtime.getRuntime();
		Process p = null;

		try {
			p = r.exec("date +%Y-%m-%dT%X");
			p.waitFor();
			// Se obtiene el stream de salida del programa
			InputStream is = p.getInputStream();

			/*
			 * Se prepara un bufferedReader para poder leer la salida más
			 * comodamente.
			 */
			BufferedReader br = new BufferedReader(new InputStreamReader(is));

			// Se lee la primera linea
			salida = br.readLine().trim();

		} catch (Exception e) {
		}
		return salida;
	}

	/**
	 * Funcion que genera el fichero XML que se pasara al servicio WEB
	 * 
	 * @return
	 */
	public static String generarFichero(String[] parametro) {

		// Fichero XML
		String fichero = new String();

		// Poner la cabecera XML
		fichero += "<?xml version=\"1.0\" standalone=\"yes\"?>\n<AuditDataSet xmlns=\"http://tempuri.org/AuditDataSet.xsd\">\n";
		fichero += "\t<GAS_HOST_AUDIT>\n";
		fichero += "\t\t<ID>-1</ID>\n";
		fichero += "\t\t<AUDIT_ID>-1</AUDIT_ID>\n";
		fichero += "\t\t<HOST_ID>" + obtenerHostID() + "</HOST_ID>\n";
		fichero += "\t\t<AUDIT_DATETIME>" + obtenerFecha()
				+ "</AUDIT_DATETIME>\n";
		fichero += "\t</GAS_HOST_AUDIT>\n";

		// Cuerpo del fichero XML
		for (int i = 0; i < parametro.length; i++) {
			if (parametro[i].intern().equals("Users and Groups")) {
				System.out.println("Start Users and Groups");
				fichero += obtenerUsersGroups();
				System.out.println("End Users and Groups");
			} else if (parametro[i].intern().equals("SecuritySettings")) {
				System.out.println("Start SecuritySettings");
				fichero += obtenerSecuritySettings();
				System.out.println("End SecuritySettings");
			} else if (parametro[i].intern().equals("Open Ports")) {
				System.out.println("Start Open Ports");
				fichero += obtenerOpenPorts();
				System.out.println("End Open Ports");
			} else if (parametro[i].intern().equals("NetworkAdapters")) {
				System.out.println("Start NetworkAdapters");
				fichero += obtenerNetworkAdapters();
				System.out.println("End NetworkAdapters");
			} else if (parametro[i].intern().equals("Updates")) {
				System.out.println("Start Updates");
				fichero += obtenerUpdates();
				System.out.println("End Updates");
			} else if (parametro[i].intern().equals("Logs")) {
				System.out.println("Start Logs");
				fichero += obtenerLogs();
				System.out.println("End Logs");
			} else if (parametro[i].intern().equals("Hardware")) {
				System.out.println("Start Hardware");
				fichero += obtenerHardware();
				System.out.println("End Hardware");
			} else if (parametro[i].intern().equals("Software")) {
				System.out.println("Start Software");
				fichero += obtenerSoftware();
				System.out.println("End Software");
			} else if (parametro[i].intern().equals("Processes")) {
				System.out.println("Start Processes");
				fichero += obtenerProcesos();
				System.out.println("End Processes");
			}
		}

		fichero += "</AuditDataSet>";

		// Devuelvo el fichero generado
		return fichero;
	}

	private static boolean noWebService = false;
	private static String webServiceUrl = "http://localhost/GASWebServices/GASWebServiceUntyped.asmx";
	private static String[] auditOptions = null;
	private static boolean test = false;
	private static String testFilePath = "auditDS.xml";
	private static boolean writeToFile = false;

	public static void main(String[] args) {
		GASWebServiceUntypedLocator locator;
		GASWebServiceUntypedSoap port;
		String auditCode;
		String xmlResult;

		readParameters(args);

		try {
			if (noWebService) {
				System.out.println("Without web service");

				if (test)
					xmlResult = readFileAsString(testFilePath);
				else
					xmlResult = generarFichero(auditOptions);

				System.out.println("XML generated");

				writeStringToFile(xmlResult, "auditDS.xml");

				System.out.println("Audit XML correctly sent.");
			} else {
				System.out.println("With web service. Generating web service with URL: " + webServiceUrl);
				
				locator = new GASWebServiceUntypedLocator();
				locator.setEndpointAddress("GASWebServiceUntypedSoap", webServiceUrl);
				port = locator.getGASWebServiceUntypedSoap();

				System.out.println("Web service generated with URL: " + webServiceUrl);

				auditCode = "";
				auditCode = port.getLastAuditCode();
				
				System.out.println("Audit Code: " + auditCode);
				
				if (auditCode != "") {
					auditOptions = port.getAuditOptions(auditCode);

					System.out.print("Audit options: ");
					for (int i = 0; i < auditOptions.length; i++)
					{
						System.out.print(auditOptions[i]);
						if (i != auditOptions.length - 1)
							System.out.print(", ");
					}
					System.out.println();
					
					if (test)
						xmlResult = readFileAsString(testFilePath);
					else
						xmlResult = generarFichero(auditOptions);

					System.out.println("XML generated");

					if (writeToFile)
						writeStringToFile(xmlResult, "auditDS.xml");

					port.saveHostAudit(xmlResult, auditCode);

					System.out.println("Audit XML correctly sent.");
				} else {
					System.out.println("You have to register audit options in GAS tool!!");
				}
			}
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}

	}

	private static String readFileAsString(String filePath)
			throws java.io.IOException {
		StringBuffer fileData = new StringBuffer(1000);
		BufferedReader reader = new BufferedReader(new FileReader(filePath));
		char[] buf = new char[1024];
		int numRead = 0;
		while ((numRead = reader.read(buf)) != -1) {
			String readData = String.valueOf(buf, 0, numRead);
			fileData.append(readData);
			buf = new char[1024];
		}
		reader.close();
		return fileData.toString();
	}

	public static void writeStringToFile(String content, String filePath)
			throws java.io.IOException {
		File outFile = new File(filePath);
		FileWriter out = new FileWriter(outFile);
		out.write(content);
		out.close();
	}

	private static void readParameters(String[] args) {
		int equalPosition;
		String key;
		String value;

		for (int i = 0; i < args.length; i++) {
			equalPosition = args[i].indexOf("=");

			if (equalPosition == -1) {
				System.out
						.println("Incorrect parameters. Options webServiceUrl=<URL> | noWebService=<true|false> | auditOptions=<commaSeparatedAuditOptions> | writeToFile=<true|false> | test=<true|false> | testFilePath=<file path to send to Web Service>.");
			} else {
				key = args[i].substring(0, equalPosition).trim();
				value = args[i].substring(equalPosition + 1).trim();

				if (key.equals("noWebService")) {
					noWebService = Boolean.valueOf(value).booleanValue();
				} else if (key.equals("test")) {
					test = Boolean.valueOf(value).booleanValue();
				} else if (key.equals("writeToFile")) {
					writeToFile = Boolean.valueOf(value).booleanValue();
				} else if (key.equals("webServiceUrl")) {
					webServiceUrl = value;
				} else if (key.equals("testFilePath")) {
					testFilePath = value;
				} else if (key.equals("auditOptions")) {
					auditOptions = value.split(",");
				}
			}
		}
	}

}
